/**
 * Description:     对bmp灰度位图进行灰度增强。
 * Function:        int imgGL(GARYSCALEBIT garyscalebit, int a, int b);     线性灰度增强
 *                  int imgGE(GARYSCALEBIT garyscalebit, int a, int b);     对数灰度增强
 * Solution:        如果你在使用本头文件时发现了任何问题，请报告issue.
 * Contributer:     叶月枫
 */

#ifndef imgG_h
#define imgG_h

#include <stdio.h>
#include <math.h>

// 声明函数
int imgGL(GARYSCALEBIT garyscalebit, int a, int b);
int imgGE(GARYSCALEBIT garyscalebit, int a, int b);

/**
 * Function:    对bmp灰度位图进行线性灰度增强
 * Parameter:   garyscalebit    [in]GARYSCALEBIT结构体，包括原图的灰度信息、数据个数和排列顺序
 * Return:      0               操作成功
 */
int imgGL(GARYSCALEBIT garyscalebit, int a, int b)
{
    // 获取原有灰度的范围
    int max = 0, min = 255;
    for (int i = 0; i < garyscalebit.dataCount; i++)
    {
        if (garyscalebit.garyscale[i] > max)
        {
            max = garyscalebit.garyscale[i];
        }
        if (garyscalebit.garyscale[i] < min)
        {
            min = garyscalebit.garyscale[i];
        }
    }

    // 计算线性变换的结果
    for (int i = 0; i < garyscalebit.dataCount; i++)
    {
        garyscalebit.garyscale[i] = a + (float)(b - a) * (garyscalebit.garyscale[i] - min) / (max - min);
    }

    // 对结果进行四舍五入
    for (unsigned int i = 0; i < garyscalebit.dataCount; i++)
    {
        garyscalebit.garyscale[i] = round(garyscalebit.garyscale[i]);
    }
    return 0;
}

/**
 * Function:    对bmp灰度位图进行对数灰度增强
 * Parameter:   garyscalebit    [in]GARYSCALEBIT结构体，包括原图的灰度信息、数据个数和排列顺序
 * Return:      0               操作成功
 */
int imgGE(GARYSCALEBIT garyscalebit, int a, int b)
{
    // 计算对数变换的结果
    for (int i = 0; i < garyscalebit.dataCount; i++)
    {
        // 临时用于进行计算的数组
        float *temp = (float *)calloc(garyscalebit.dataCount, sizeof(float));
        
        // 计算结果
        temp[i] = a + (log((double)garyscalebit.garyscale[i] + 1) * b);

        // 优化不合理的值
        if (temp[i] <= 0)
        {
            garyscalebit.garyscale[i] = 0;
        }
        else if (temp[i] >= 255)
        {
            garyscalebit.garyscale[i] = 255;
        }
        else
        {
            // 四舍五入
            garyscalebit.garyscale[i] = round(temp[i]);
        }

        // 释放空间
        free(temp);
    }
    return 0;
}

#endif